home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_100 / 113_01 / a68get.c < prev    next >
Text File  |  1985-03-09  |  10KB  |  363 lines

  1. /*
  2.     HEADER:        CUG113;
  3.     TITLE:        6800 Cross-Assembler (BDS C Version);
  4.     FILENAME:    A68GET.C;
  5.     VERSION:    2.6;
  6.     DATE:        07/22/1985;
  7.  
  8.     DESCRIPTION:    "This program lets you use your CP/M-80-based computer
  9.             to assemble code for the Motorola 6800, 6801, 6802,
  10.             6803, 6808, and 68701 microprocessors.  The program is
  11.             written in BDS C for the best possible performance on
  12.             8-bit machines.  All assembler features are supported
  13.             except relocation, linkage, listing control, and
  14.             macros.";
  15.  
  16.     KEYWORDS:    Software Development, Assemblers, Cross-Assemblers,
  17.             Motorola, MC6800, MC6801;
  18.  
  19.     SEE-ALSO:    CUG149, 6801 Cross-Assembler (Portable);
  20.  
  21.     SYSTEM:        CP/M-80;
  22.     COMPILERS:    BDS C;
  23.  
  24.     WARNINGS:    "This package is specifically tailored to CP/M-80
  25.             machines and the rather non-standard, but high-
  26.             performance BDS C compiler.  For other environments,
  27.             use the portable version of this package on CUG149.";
  28.  
  29.     AUTHORS:    William C. Colley III;
  30. */
  31.  
  32. /*
  33.     6800/6801 Cross-Assembler  v. 2.6
  34.  
  35.     May, 1980
  36.  
  37.     July, 1980 -- Rev. 2.2 consisting of fixing the M errors that
  38.         come from forward references in FDB and FCB pseudo-ops.
  39.  
  40.     October, 1980 -- Rev. 2.3 consisting of updating the assembly
  41.         language file and I/O routines to match and take
  42.         advantage of BDS C V1.4.
  43.  
  44.     October, 1983 -- Rev. 2.4 consisting of adding the CPU pseudo-op,
  45.         adding the 6801 CPU's extra opcodes, and speeding up the
  46.         code a bit.
  47.  
  48.     September, 1984 -- Rev. 2.5 consisting of fixing bugs with the symbol
  49.         table sort, the writing of files to specified drives, and the
  50.         handling of blank input lines.
  51.  
  52.     June, 1985 -- Rev. 2.6 consisting of fixing a bug in the IF block
  53.         nesting mechanism.
  54.  
  55.     Copyright (c) 1980,83,84,85 William C. Colley, III.
  56.  
  57. File:    a68get.c
  58.  
  59. Routines to get source text from the disk and return it in
  60. manageable chunks such as operators, labels, opcodes, etc.
  61. */
  62.  
  63. /*  Get Globals:  */
  64.  
  65. #include "a68.h"
  66.  
  67. /*
  68. Function to get an opcode from the present source line and return
  69. its value and attributes.  The function returns -1 if no opcode was
  70. on the line, 0 if the opcode was not in the opcode table, and 1
  71. otherwise.  If the opcode was on the line, but not in the table, the
  72. error is marked up.
  73. */
  74.  
  75. getopcod(value,attrib)
  76. char *value, *attrib;
  77. {
  78.     char temp[SYMLEN+1], getopc(), getchr();
  79.  
  80.     switch (getchr(value,SKIP)) {
  81.     case ALPHA:    backchr;  getname(temp);
  82.             if (bsearch(temp,value,attrib,0,numopcs(),getopc))
  83.                 return 1;
  84.             markerr('O');  return 0;
  85.  
  86.     default:    markerr('S');  return -1;
  87.  
  88.     case END_LIN:    return -1;
  89.     }
  90. }
  91.  
  92. /*
  93. Function to look up an item in a fixed table by binary search.  The function
  94. returns 1 if the item was found, 0 if not.  name points to the name to be
  95. looked up (null terminated).  value and attrib catch two bytes of parameters
  96. attached to the item if the item is found.  high and low are for the benefit of
  97. the recursion.  For the first call use the number of items in the table for
  98. high and 0 for low.  table is a pointer to a function to get an item from the
  99. appropriate table.  Note that in the comparison, lower case is converted to
  100. upper case.
  101. */
  102.  
  103. bsearch(name,value,attrib,low,high,table)
  104. char *name, *value, *attrib, (*table)();
  105. int low, high;
  106. {
  107.     char temp[5], *pntr1, *pntr2;
  108.     int t, check;
  109.  
  110.     if (low > high) return 0;
  111.     check = low + (high - low >> 1);
  112.     (*table)(check,temp,value,attrib);
  113.     pntr1 = temp;  pntr2 = name;
  114.     while ((t = toupper(*pntr2++) - *pntr1) == 0 && *pntr1++);
  115.     if (!t) return 1;
  116.     return t > 0 ? bsearch(name,value,attrib,check+1,high,table) :
  117.     bsearch(name,value,attrib,low,check-1,table);
  118. }
  119.  
  120. /*
  121. Function to push back an item so that getitem will retrieve it
  122. a second time.  Only one level of pushback is supported.
  123. */
  124.  
  125. backitem(value,attrib)
  126. unsigned value, attrib;
  127. {
  128.     oldvalu = value;  oldattr = attrib;  backflg = TRUE;
  129. }
  130.  
  131. /*
  132. Function to get an item from the present source line.  Items may be
  133. looked-up symbols, numeric constants, string constants, operators, etc.
  134. The function returns the attribute of the item gotten.  value is a
  135. pointer to where the value of the item will be stored, and quoteflg
  136. determines whether getitem will look for one- and two-character string
  137. constants or not.
  138. */
  139.  
  140. getitem(value,quoteflg)
  141. unsigned *value;
  142. char quoteflg;
  143. {
  144.     char c, c1, attrib, *tmpptr, temp[2*SYMLEN], getchr();
  145.     unsigned base, u;
  146.  
  147.     if (backflg) {
  148.     backflg = FALSE;  *value = oldvalu;  return oldattr;
  149.     }
  150.  
  151.     switch (attrib = getchr(&c,SKIP)) {
  152.     case END_LIN:
  153.     case COMMA:
  154.     case IMMED:    return attrib;
  155.  
  156.     case NUMERIC:    backchr;  getnum(value,&base);  return VALUE;
  157.  
  158.     case BAS_DES:    switch (c) {
  159.                 case '$':    base = 16;  break;
  160.  
  161.                 case '@':    base = 8;  break;
  162.  
  163.                 case '%':    base = 2;  break;
  164.             }
  165.             *value = 0;
  166.             while ((attrib = getchr(&c,NOSKIP)) == NUMERIC |                    attrib == ALPHA)
  167.                 *value = *value * base + _aton(toupper(c),base);
  168.             backchr;  return VALUE;
  169.  
  170.     case OPERATR:    switch (c) {
  171.                 case '>':
  172.                 case '=':
  173.                 case '<':    getchr(&c1,NOSKIP);
  174.                     if (c == '>') {
  175.                         if (c1 == '=') c = GRTEQ;
  176.                         else if (c1 == '<') c = NOTEQ;
  177.                         else backchr;
  178.                     }
  179.                     else if (c == '=') {
  180.                         if (c1 == '>') c = GRTEQ;
  181.                         else if (c1 == '<') c = LESEQ;
  182.                         else backchr;
  183.                     }
  184.                     else if (c == '<') {
  185.                         if (c1 == '>') c = NOTEQ;
  186.                         else if (c1 == '=') c1 = LESEQ;
  187.                         else backchr;
  188.                     }
  189.                     else backchr;
  190.  
  191.                 default:    *value = c;  return attrib;
  192.             }
  193.  
  194.     case QUOTE:    if (quoteflg) { *value = c;  return attrib; }
  195.             tmpptr = temp;  attrib = 0;
  196.             while ((getchr(&c1,NOSKIP),c1) != '\n' &&  c1 != c)
  197.                 if (++attrib <= 2) *tmpptr++ = c1;
  198.             if (c1 == '\n' || attrib > 2) {
  199.                 if (c1 == '\n') backchr;
  200.                 evalerr = TRUE;  markerr('"');  return VALUE;
  201.             }
  202.             tmpptr = temp;
  203.             for (*value = 0; attrib; --attrib)
  204.                 *value = (*value << 8) + *tmpptr++;
  205.             return VALUE;
  206.  
  207.     case ALPHA:    backchr;  getname(temp);
  208.             if (!temp[1]) {
  209.                 *value = toupper(temp[0]);
  210.                 switch (*value) {
  211.                 case 'A':
  212.                 case 'B':
  213.                 case 'X':   return REGISTR;
  214.                 }
  215.             }
  216.             else if ((*value = chkoprat(temp) & 0xff) != NO_OPR)
  217.                 return OPERATR;
  218.             strcat(temp,PADDING);
  219.             if (!slookup(temp)) {
  220.                 *value = sympoint -> symvalu;
  221.                 if (sympoint -> symname[0] > 0x7f) directok = FALSE;            }
  222.             else { evalerr = TRUE;  markerr('U'); }
  223.             return VALUE;
  224.     }
  225. }
  226.  
  227. /*
  228. Function to get a symbol name, opcode, or label from the present source
  229. line.  The name is returned (null terminated) in buffer.  Names are
  230. terminated by any non-alphanumeric character.
  231. */
  232.  
  233. getname(buffer)
  234. char *buffer;
  235. {
  236.     char c, d, count;
  237.  
  238.     count = 0;
  239.     while ((c = getchr(&d,NOSKIP)) == ALPHA || c == NUMERIC)
  240.     if (++count <= SYMLEN) *buffer++ = d;
  241.     backchr;  *buffer = '\0';
  242. }
  243.  
  244. /*
  245. Function to check a string against the list of operators that get spelled out.
  246. This list consists of GE, GT, LE, LT, EQ, NE, AND, OR, XOR, NOT, MOD, SHL,
  247. SHR, HIGH, LOW.  The function returns the token for the operator if the
  248. string is an operator, the token NO_OPR otherwise.
  249. */
  250.  
  251. chkoprat(string)
  252. char *string;
  253. {
  254.     char s, t, getopr();
  255.  
  256.     return (bsearch(string,&s,&t,0,numoprs(),getopr)) ? t : NO_OPR;
  257. }
  258.  
  259. /*
  260. Function to get an Intel format number from the present input line.
  261. value points to the number to be returned, and base points to an
  262. unsigned where the base of the number will be saved during internal
  263. computations.  The function returns a fixed value of 1 and flags errors
  264. as it goes along.
  265. */
  266.  
  267. getnum(number,base)
  268. unsigned *number, *base;
  269. {
  270.     char c1, c2, toupper();
  271.     unsigned b;
  272.  
  273.     if ((c1 = getchr(&c2,NOSKIP)) != ALPHA && c1 != NUMERIC) {
  274.     backchr;  return 0xffff;
  275.     }
  276.  
  277.     if ((b = getnum(number,base)) == 0xffff) {
  278.     *number = 0;
  279.     switch (toupper(c2)) {
  280.         case 'H':    *base = 16;  return 1;
  281.         case 'D':    *base = 10;  return 1;
  282.         case 'O':
  283.         case 'Q':    *base = 8;  return 1;
  284.         case 'B':    *base = 2;  return 1;
  285.         default:    *base =